package com.inyourcode.core.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;

/**
 * @author JackLei
 */
public class JWTUtil {
    private static final String KEY_issuer = "u1";
    private static final String KEY_UID = "redstar";
    private static final String KEY_EXTEND_DATA = "extendData";
    private static JWTUtil instance;
    private String secretKey;
    private long expireTime;
    private String issuer;

    public static JWTUtil getInstance() {
        return instance;
    }

    public JWTUtil(String secretKey, long expireTime, String issuer) {
        this.secretKey = secretKey;
        this.expireTime = expireTime;
        this.issuer = issuer;
        instance = this;
    }

    public JWTUtil(String secretKey, long expireTime) {
        this.secretKey = secretKey;
        this.expireTime = expireTime;
        this.issuer = KEY_issuer;
        instance = this;
    }

    public String create(String uid, String extendData) {
        Date date = new Date();
        Algorithm algorithm = Algorithm.HMAC256(secretKey);
        return JWT.create().withClaim(KEY_UID, uid)
                .withClaim(KEY_EXTEND_DATA, extendData)
                .withIssuer(issuer)
                .withIssuedAt(date)
                .withExpiresAt(new Date(date.getTime() + expireTime))
                .sign(algorithm);
    }

    public JWTResult parse(String token) {
        Algorithm algorithm = Algorithm.HMAC256(secretKey);
        JWTVerifier verifier = JWT.require(algorithm).withIssuer(issuer).build();
        try {
            DecodedJWT jwt = verifier.verify(token);
            String uid = jwt.getClaims().get(KEY_UID).asString();
            String data = jwt.getClaims().get(KEY_EXTEND_DATA).asString();
            return new JWTResult(uid, data);
        } catch (JWTVerificationException e) {
            return JWTResult.EXCEPTION;
        }
    }

    public static class JWTResult {
        public static final JWTResult EXCEPTION = new JWTResult("", "");

        private String uid;
        private String extendData;

        JWTResult(String uid, String extendData) {
            this.uid = uid;
            this.extendData = extendData;
        }

        public String getUid() {
            return uid;
        }

        public String getExtendData() {
            return extendData;
        }
    }
}
